package com.qf.leadnewscommon.minio;

import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MinioOperator {

    private MinioClient minioClient;
    private MinioPorperties minioPorperties;

    public MinioOperator(MinioClient minioClient, MinioPorperties minioPorperties) {
        this.minioClient = minioClient;
        this.minioPorperties = minioPorperties;
    }

    /**
     *
     * @param is  需要上传的文件对应的输入流对象
     * @param filename 需要上传的文件原始文件名 -- 需要针对这个文件名进行目录分离处理
     * @return
     * @throws Exception
     */
    public String uploadHtml(InputStream is,String filename) throws Exception{
        filename = buildPathName(filename);
        PutObjectArgs putArgs = PutObjectArgs.builder()
                //目标桶名称
                .bucket(minioPorperties.getBucket())
                //上传文件类型
                .contentType("text/html")
                //上传后，文件名称（目录分离+防重名）
                .object(filename)
                .stream(is,is.available(),-1)
                .build();
        minioClient.putObject(putArgs);

        String fileUrl = minioPorperties.getEndpoint() + "/" + minioPorperties.getBucket() + "/" + filename;
        return fileUrl;
    }

    /**
     * 上传图片
     * @param is
     * @param filename
     * @return
     * @throws Exception
     */
    public String uploadImage(InputStream is,String filename) throws Exception{
        filename = buildPathName(filename);
        PutObjectArgs putArgs = PutObjectArgs.builder()
                //目标桶名称
                .bucket(minioPorperties.getBucket())
                //上传文件类型
                .contentType("image/jpg")
                //上传后，文件名称（目录分离+防重名）
                .object(filename)
                .stream(is,is.available(),-1)
                .build();
        minioClient.putObject(putArgs);

        String fileUrl = minioPorperties.getEndpoint() + "/" + minioPorperties.getBucket() + "/" + filename;
        return fileUrl;
    }

    /**
     * 根据url删除图片
     * @param pathUrl
     */
    public void delete(String pathUrl) {
        String key = pathUrl.replace(minioPorperties.getEndpoint()+"/","");
        int index = key.indexOf("/");
        String bucket = key.substring(0,index);
        String filePath = key.substring(index+1);
        // 删除Objects
        RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
        try {
            minioClient.removeObject(removeObjectArgs);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据url下载图片
     * @param pathUrl
     * @return
     */
    public byte[] downLoadFile(String pathUrl)  {
        String key = pathUrl.replace(minioPorperties.getEndpoint()+"/","");
        int index = key.indexOf("/");
        String bucket = key.substring(0,index);
        String filePath = key.substring(index+1);
        InputStream inputStream = null;
        try {
            inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minioPorperties.getBucket()).object(filePath).build());
        } catch (Exception e) {
            e.printStackTrace();
        }

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while (true) {
            try {
                if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            byteArrayOutputStream.write(buff, 0, rc);
        }
        return byteArrayOutputStream.toByteArray();
    }

    /**
     * 通过原始文件名生成一个目录分离的文件路径名称
     *  ① 根据文件名获取一个md5值或者获取一个随机生成的uuid值   hdsjahgjagjahgdj
     *       获取这个字符串的第一个字符作为一级目录，第二个字符作为二级目录，.....
     *
     *  ② 根据日期生成  年/月/日
     * @param filename
     * @return
     */
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    private String buildPathName(String filename) {
        String dirPath = sdf.format(new Date());
        return dirPath + "/" + filename;  // 2023/02/10/test.html
    }
}
